//
// Created by denglibin on 2021/4/10 0010.
//
#include "draw.h"
/**
 * 根据精灵位置 计算 元素在窗口中的位置
 * @param spiritX
 * @param mapX
 * @param mapW
 * @param winW
 * @return
 */
static int getWinX(int spiritX, int mapX, int mapW, int winW);

void drawTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                 const SDL_Rect* srcRect, const SDL_Rect* distRect){

    int r = SDL_RenderCopy(renderer, texture, srcRect, distRect);
    if (r != 0){
        SDL_Log("Can not copy render %s\n", SDL_GetError());
        exit(1);
    }
}
/**
 * 绘制星空
 * @param bg
 * @param renderer
 */
static void drawStar(Background* bg,GameWindow * gameWindow, int spiritX);
/**
 * 绘制山
 * @param bg
 * @param gameWindow
 * @param spiritX
 */
static void drawMountain(Background* bg,GameWindow * gameWindow, int spiritX);

/**
 * 绘制丛林
 * @param bg
 * @param gameWindow
 * @param spiritX
 */
static void drawJungle(Background* bg,GameWindow * gameWindow, int spiritX);

/**
 * 路
 * @param bg
 * @param gameWindow
 * @param spiritX
 */
static void drawRoad(Background* bg,GameWindow * gameWindow, int spiritX);

/**
 * 石头（路基）
 * @param bg
 * @param gameWindow
 * @param spiritX
 */
static void drawStone(Background* bg,GameWindow * gameWindow,SDL_Rect *disRect);


void drawBg(Background* bg, GameWindow * gameWindow,int spiritX){

    //绘制星空
    drawStar(bg, gameWindow, spiritX);
    //绘制山
    drawMountain(bg, gameWindow, spiritX);
    //路
    drawRoad(bg, gameWindow, spiritX);
    //丛林
    drawJungle(bg, gameWindow, spiritX);

}

void drawSpirit(Game* game){
    SDL_Rect srcRect = {0, 0, game->spirit->w, game->spirit->h};
    int x = game->spirit->x;

    if(x >= game->gameWindow->width / 2 && x < game->bg->width - game->gameWindow->width/2){
        x = game->gameWindow->width / 2;
    }
    if(x >=  game->bg->width - game->gameWindow->width/2){
        x =  game->gameWindow->width - (game->bg->width - x);
    }

    SDL_Rect disRect = {x , game->spirit->y, srcRect.w, srcRect.h};
    drawTexture(game->gameWindow->sdl_win_renderer, game->spirit->pTexture, &srcRect, &disRect);
}

static void drawStar(Background* bg, GameWindow * gameWindow, int spiritX){
    SDL_Rect srcRect = {0, 0, 65, 50}; //纹理中星空片段
    if(spiritX > gameWindow->width / 2 && spiritX < bg->width - gameWindow->width/2){
        bg->starStartX = -(spiritX % srcRect.w); //超出窗口范围的直接跳过
    }
    SDL_Rect disRect = {bg->starStartX, 0, srcRect.w, srcRect.h};
    while (disRect.x <= gameWindow->width){
        drawTexture(gameWindow->sdl_win_renderer, bg->texture, &srcRect, &disRect);
        disRect.x += disRect.w;
    }

}

static void drawMountain(Background* bg,GameWindow * gameWindow, int spiritX){
    SDL_Rect srcRect = {0, 0, 0, 0}; //纹理中山
    SDL_Rect disRect = {0, 0,0,0};

    Mountain ** pMountains = bg->mountains;
    for(int i = 0; i < sizeof(bg->mountains) / sizeof(Mountain*); i++){
        if(!pMountains[i]){
            continue;
        }
        pMountains[i]->winX = getWinX(spiritX, pMountains[i]->mapX, bg->width, gameWindow->width);


        srcRect.x = pMountains[i]->srcX;
        srcRect.y = pMountains[i]->srcY;
        srcRect.w = pMountains[i]->srcW;
        srcRect.h = pMountains[i]->srcH;

        disRect.x =  pMountains[i]->winX;
        disRect.y =  pMountains[i]->mapY;
        disRect.w =  srcRect.w;
        disRect.h =  srcRect.h;

        drawTexture(gameWindow->sdl_win_renderer, bg->texture, &srcRect, &disRect);
    }
}

static void drawJungle(Background* bg,GameWindow * gameWindow, int spiritX){
    SDL_Rect srcRect = {0, 95, 80, 30}; //纹理中丛林片段
    SDL_Rect disRect = {0, 100, srcRect.w, srcRect.h};
    int num = bg->width / disRect.w + 1;
    int j = 0;
    while (j < num){
        disRect.x = getWinX(spiritX, disRect.w * j, bg->width, gameWindow->width);
        drawTexture(gameWindow->sdl_win_renderer, bg->texture, &srcRect, &disRect);
        disRect.x += disRect.w;
        j++;
    }
}

static void drawRoad(Background* bg,GameWindow * gameWindow, int spiritX){
    SDL_Rect srcRect = {65, 130, 35, 15}; //纹理中路面片段
    SDL_Rect disRect = {0, 0, srcRect.w, srcRect.h};
    SDL_Rect stoneDisRect = {0, 0, disRect.w, 30};
    int mapX;
    int num;
    for(int i = 0; i < sizeof(bg->roadPositions) / sizeof(RoadPosition*); i++){
        disRect.y = bg->roadPositions[i]->y;
        stoneDisRect.y = disRect.y + disRect.h;
        num =  (bg->roadPositions[i]->endX - bg->roadPositions[i]->startX)/ disRect.w + 1;
        for(int j = 0; j < num; j++){
            mapX = bg->roadPositions[i]->startX + (j * disRect.w);
            disRect.x = getWinX(spiritX, mapX, bg->width, gameWindow->width);
            drawTexture(gameWindow->sdl_win_renderer, bg->texture, &srcRect, &disRect);

            stoneDisRect.x = disRect.x;
            drawStone(bg, gameWindow, &stoneDisRect);
        }
    }

}

static void drawStone(Background* bg,GameWindow * gameWindow,SDL_Rect *disRect){

    SDL_Rect srcRect = {0, 130, disRect->w, 30}; //纹理中石头片段
    int num  = 5; //层
    for (int i = 0; i < num; i++) {
        drawTexture(gameWindow->sdl_win_renderer, bg->texture, &srcRect, disRect);
        disRect->y += disRect ->h;
    }
    disRect->y -= disRect->h * num; //还原
    disRect->x += disRect->w;

}

static int getWinX(int spiritX, int mapX, int mapW, int winW){
    if(spiritX < winW / 2){
        return mapX;
    }else if(spiritX >= winW / 2 && spiritX <= mapW - winW/2){
        return  mapX - spiritX + winW/2;
    }else if (spiritX > mapW - winW/2){
        return winW - (mapW - mapX);
    }
}